﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using QualityStormCommon;

namespace QualityStorm {
    public partial class FrmMain : Form {
        Module[] modules = null;
        public FrmMain() {
            InitializeComponent();
        }

        private void toolStripContainer1_ContentPanel_Load(object sender, EventArgs e) {

        }

        private void newToolStripMenuItem_Click(object sender, EventArgs e) {
            if (treeView1.SelectedNode.Text == "Roles") {
                FrmRoles frm = new FrmRoles();
                frm.ShowDialog();
            }
        }

        private void FrmMain_Load(object sender, EventArgs e) {
            if (GlobalObjects.Connections.Count == 0) {
                FrmLogin frm = new FrmLogin();
                frm.ShowDialog();
                if (GlobalObjects.Connections.Count != 0) {
                    treeView1.Nodes.Clear();
                    BuildConnectionContextTree(GlobalObjects.Connections[0]);
                    treeView1.SelectedNode = treeView1.Nodes[0];
                    treeView1.SelectedNode.Expand();

                }

            }
        }

        private void BuildConnectionContextTree(ConnectionContext context) {
            // Root Element
            TreeNode rootNode = new TreeNode(context.Login + "@" + context.ServerName);
            treeView1.Nodes.Add(rootNode);

            rootNode.Tag = context;
            modules = context.Service.GetModules();

            // Process Models Branch


            if (context.Service.TestObjectPermission(FindModule(modules, "Process Models").Guid, QualityStormCommon.PermissionType.View)) {
                TreeNode newNode = new TreeNode("Process Models", TreeViewIconIndexes.ProcessModels, TreeViewIconIndexes.ProcessModels);
                rootNode.Nodes.Add(newNode);
                ConnectionContextBag bag = new ConnectionContextBag();
                bag.Context = context;
                bag.Module = FindModule(modules, "Process Models");
                bag.ParentGuid = bag.Module.Guid;

                newNode.Tag = bag;
                PopulateNode(newNode);
            }

            // Queries Branch

            if (context.Service.TestObjectPermission(FindModule(modules, "Queries").Guid, QualityStormCommon.PermissionType.View)) {
                TreeNode newNode = new TreeNode("Queries", TreeViewIconIndexes.Queries, TreeViewIconIndexes.Queries);
                rootNode.Nodes.Add(newNode);

                ConnectionContextBag bag = new ConnectionContextBag();
                bag.Context = context;
                bag.Module = FindModule(modules, "Queries");
                bag.ParentGuid = bag.Module.Guid;

                newNode.Tag = bag;
                PopulateNode(newNode);

            }

            // Reports Branch

            if (context.Service.TestObjectPermission(FindModule(modules, "Reports").Guid, QualityStormCommon.PermissionType.View)) {
                TreeNode newNode = new TreeNode("Reports", TreeViewIconIndexes.Reports, TreeViewIconIndexes.Reports);
                rootNode.Nodes.Add(newNode);
                ConnectionContextBag bag = new ConnectionContextBag();
                bag.Context = context;
                bag.Module = FindModule(modules, "Reports");
                bag.ParentGuid = bag.Module.Guid;

                newNode.Tag = bag;
                PopulateNode(newNode);
            }

            // Dashboards Branch

            if (context.Service.TestObjectPermission(FindModule(modules, "Dashboards").Guid, QualityStormCommon.PermissionType.View)) {
                TreeNode newNode = new TreeNode("Dashboards", TreeViewIconIndexes.Dashboards, TreeViewIconIndexes.Dashboards);
                rootNode.Nodes.Add(newNode);
                ConnectionContextBag bag = new ConnectionContextBag();
                bag.Context = context;
                bag.Module = FindModule(modules, "Dashboards");
                bag.ParentGuid = bag.Module.Guid;

                newNode.Tag = bag;
                PopulateNode(newNode);
            }

            // ControlCharts Branch

            if (context.Service.TestObjectPermission(FindModule(modules, "Control Charts").Guid, QualityStormCommon.PermissionType.View)) {
                TreeNode newNode = new TreeNode("Control Charts", TreeViewIconIndexes.ControlCharts, TreeViewIconIndexes.ControlCharts);
                rootNode.Nodes.Add(newNode);
                ConnectionContextBag bag = new ConnectionContextBag();
                bag.Context = context;
                bag.Module = FindModule(modules, "Control Charts");
                bag.ParentGuid = bag.Module.Guid;

                newNode.Tag = bag;
                PopulateNode(newNode);
            }


            // Charts Branch

            if (context.Service.TestObjectPermission(FindModule(modules, "Charts").Guid, QualityStormCommon.PermissionType.View)) {
                TreeNode newNode = new TreeNode("Charts", TreeViewIconIndexes.Charts, TreeViewIconIndexes.Charts);
                rootNode.Nodes.Add(newNode);
                ConnectionContextBag bag = new ConnectionContextBag();
                bag.Context = context;
                bag.Module = FindModule(modules, "Charts");
                bag.ParentGuid = bag.Module.Guid;

                newNode.Tag = bag;
                PopulateNode(newNode);
            }

            // Control Panel Root

            TreeNode controlPanel = new TreeNode("Control Panel", TreeViewIconIndexes.ControlPanel, TreeViewIconIndexes.ControlPanel);

            // Roles

            if (context.Service.TestObjectPermission(FindModule(modules, "Roles").Guid, QualityStormCommon.PermissionType.View)) {
                TreeNode newNode = new TreeNode("Roles", TreeViewIconIndexes.Roles, TreeViewIconIndexes.Roles);
                controlPanel.Nodes.Add(newNode);
                ConnectionContextBag bag = new ConnectionContextBag();
                bag.Context = context;
                bag.Module = FindModule(modules, "Roles");
                bag.ParentGuid = bag.Module.Guid;

                newNode.Tag = bag;
                PopulateNode(newNode);
            }

            //Users
            if (context.Service.TestObjectPermission(FindModule(modules, "Users").Guid, QualityStormCommon.PermissionType.View)) {
                TreeNode newNode = new TreeNode("Users", TreeViewIconIndexes.Users, TreeViewIconIndexes.Users);
                controlPanel.Nodes.Add(newNode);
                ConnectionContextBag bag = new ConnectionContextBag();
                bag.Context = context;
                bag.Module = FindModule(modules, "Users");
                bag.ParentGuid = bag.Module.Guid;

                newNode.Tag = bag;
                PopulateNode(newNode);
            }


            //External Connections
            if (context.Service.TestObjectPermission(FindModule(modules, "External Connections").Guid, QualityStormCommon.PermissionType.View)) {
                TreeNode newNode = new TreeNode("External Connections", TreeViewIconIndexes.ExternalConnections, TreeViewIconIndexes.ExternalConnections);
                controlPanel.Nodes.Add(newNode);
                ConnectionContextBag bag = new ConnectionContextBag();
                bag.Context = context;
                bag.Module = FindModule(modules, "External Connections");
                bag.ParentGuid = bag.Module.Guid;

                newNode.Tag = bag;
                PopulateNode(newNode);
            }

            //Devices
            if (context.Service.TestObjectPermission(FindModule(modules, "Devices").Guid, QualityStormCommon.PermissionType.View)) {
                TreeNode newNode = new TreeNode("Devices", TreeViewIconIndexes.Devices, TreeViewIconIndexes.Devices);
                controlPanel.Nodes.Add(newNode);
                ConnectionContextBag bag = new ConnectionContextBag();
                bag.Context = context;
                bag.Module = FindModule(modules, "Devices");
                bag.ParentGuid = bag.Module.Guid;

                newNode.Tag = bag;
                PopulateNode(newNode);
            }

            //Products
            if (context.Service.TestObjectPermission(FindModule(modules, "Products").Guid, QualityStormCommon.PermissionType.View)) {
                TreeNode newNode = new TreeNode("Products", TreeViewIconIndexes.Products, TreeViewIconIndexes.Products);
                controlPanel.Nodes.Add(newNode);
                ConnectionContextBag bag = new ConnectionContextBag();
                bag.Context = context;
                bag.Module = FindModule(modules, "Products");
                bag.ParentGuid = bag.Module.Guid;

                newNode.Tag = bag;
                PopulateNode(newNode);
            }

            if (controlPanel.Nodes.Count > 0) {
                rootNode.Nodes.Add(controlPanel);
            }


        }

        private void PopulateNode(TreeNode selectedNode) {
            // Common for every Module
            Guid parent=Guid.Empty;
            ConnectionContextBag bag = selectedNode.Tag as ConnectionContextBag;
            if (bag != null) {
                if (bag.Folder == null) {
                    parent = bag.Module.Guid;

                } else {
                    parent = bag.Folder.Guid;
                }

                // Folders in TreeView
                if (selectedNode.Nodes.Count == 0) {
                    try {
                        Folder[] folders = bag.Context.Service.GetFolders(parent);
                        if (folders != null)
                            foreach (Folder folder in folders) {
                                TreeNode newNode = new TreeNode(folder.Name, TreeViewIconIndexes.FoldersClosed, TreeViewIconIndexes.FoldersOpened);
                                ConnectionContextBag newBag = new ConnectionContextBag();
                                newBag.Context = bag.Context;
                                newBag.Folder = folder;
                                newBag.Module = bag.Module;
                                newBag.ParentGuid = (Guid)folder.Parent;
                                newNode.Tag = newBag;
                                selectedNode.Nodes.Add(newNode);
                                PopulateNode(newNode);
                            }
                    } catch (InsufficientPrivilegesException e) {
                        MessageBox.Show("You don't have permission to see the data in this module");
                        return;
                    }

                }

                // Folders in ListView
                listView1.Items.Clear();
                foreach (TreeNode node in selectedNode.Nodes) {
                    ListViewItem item = new ListViewItem(new string[] { node.Text, node.Text });
                    item.ImageIndex = TreeViewIconIndexes.FoldersClosed;
                    listView1.Items.Add(item);
                    item.Group = listView1.Groups["Folders"];
                }


                if (selectedNode.Tag is ConnectionContextBag) {

                    switch (bag.Module.Name) {
                        case "Roles":


                            Role[] roles = bag.Context.Service.GetRoles(parent);

                            foreach (Role role in roles) {
                                ListViewItem item = new ListViewItem();
                                item.Text = role.Name;
                                item.ImageIndex = TreeViewIconIndexes.Roles;
                                item.Tag = role;

                                if (item.Text.Length > 0)
                                    if (char.IsLetter(item.Text[0])) {
                                        string letter = item.Text[0].ToString().ToUpper();
                                        item.Group = listView1.Groups[letter];
                                    } else if (char.IsNumber(item.Text[0])) {
                                        item.Group = listView1.Groups["0 - 9"];
                                    } else {
                                        item.Group = listView1.Groups["Symbols"];
                                    }
                                listView1.Items.Add(item);
                            }



                            break;

                        case "Users":


                            User[] Users = bag.Context.Service.GetUsers(parent);

                            foreach (User user in Users) {
                                ListViewItem item = new ListViewItem();
                                if (user.LastName != "") {
                                    item.Text = user.LastName + ", " + user.FirstName;
                                } else {
                                    item.Text = user.FirstName;
                                }

                                item.ImageIndex = TreeViewIconIndexes.Users;
                                item.Tag = user;
                                if (char.IsLetter(item.Text[0])) {
                                    string letter = item.Text[0].ToString();
                                    item.Group = listView1.Groups[letter];
                                } else if (char.IsNumber(item.Text[0])) {
                                    item.Group = listView1.Groups["0 - 9"];
                                } else {
                                    item.Group = listView1.Groups["Symbols"];
                                }
                                listView1.Items.Add(item);
                            }



                            break;

                        case "External Connections":
                            ExternalConnection[] ExternalConnections = bag.Context.Service.GetExternalConnections(parent);

                            foreach (ExternalConnection externalConnection in ExternalConnections) {
                                ListViewItem item = new ListViewItem();

                                item.Text = externalConnection.Name;


                                item.ImageIndex = TreeViewIconIndexes.ExternalConnections;
                                item.Tag = externalConnection;
                                if (char.IsLetter(item.Text[0])) {
                                    string letter = item.Text[0].ToString();
                                    item.Group = listView1.Groups[letter];
                                } else if (char.IsNumber(item.Text[0])) {
                                    item.Group = listView1.Groups["0 - 9"];
                                } else {
                                    item.Group = listView1.Groups["Symbols"];
                                }
                                listView1.Items.Add(item);
                            }



                            break;

                        case "Products":

                            Product[] Products = bag.Context.Service.GetProducts(parent);

                            foreach (Product product in Products) {
                                ListViewItem item = new ListViewItem();

                                item.Text = product.Name;


                                item.ImageIndex = TreeViewIconIndexes.Products;
                                item.Tag = product;
                                if (char.IsLetter(item.Text[0])) {
                                    string letter = item.Text[0].ToString();
                                    item.Group = listView1.Groups[letter];
                                } else if (char.IsNumber(item.Text[0])) {
                                    item.Group = listView1.Groups["0 - 9"];
                                } else {
                                    item.Group = listView1.Groups["Symbols"];
                                }
                                listView1.Items.Add(item);
                            }



                            break;

                        case "Process Models":

                            ProcessModel[] ProcessModels = bag.Context.Service.GetProcessModels(parent);

                            foreach (ProcessModel processModel in ProcessModels) {
                                ListViewItem item = new ListViewItem();

                                item.Text = processModel.Name;


                                item.ImageIndex = TreeViewIconIndexes.ProcessModels;
                                item.Tag = processModel;
                                if (char.IsLetter(item.Text[0])) {
                                    string letter = item.Text[0].ToString();
                                    item.Group = listView1.Groups[letter];
                                } else if (char.IsNumber(item.Text[0])) {
                                    item.Group = listView1.Groups["0 - 9"];
                                } else {
                                    item.Group = listView1.Groups["Symbols"];
                                }
                                listView1.Items.Add(item);
                            }



                            break;

                    }

                }
            }

        }

        private Module FindModule(Module[] modules, string name) {
            var module = from m in modules
                         where m.Name == name
                         select m;
            return module.First<Module>();
        }

        private void contextMenuStrip1_Opening(object sender, CancelEventArgs e) {
            ConnectionContextBag bag = treeView1.SelectedNode.Tag as ConnectionContextBag;
            foreach (ToolStripMenuItem item in contextMenuStrip1.Items) {
                item.Visible = false;
            }

            foreach (ToolStripMenuItem item in newToolStripMenuItem1.DropDownItems) {
                item.Visible = false;
            }
            if (bag.Context.Service.TestObjectPermission(bag.Module.Guid, PermissionType.Create)) {
                switch (bag.Module.Name) {
                    case "Process Models":

                        newToolStripMenuItem1.Visible = true;
                        processModelToolStripMenuItem.Visible = true;
                        folderToolStripMenuItem.Visible = true;


                        break;

                    case "Queries":
                        newToolStripMenuItem1.Visible = true;
                        queryToolStripMenuItem.Visible = true;
                        folderToolStripMenuItem.Visible = true;

                        break;

                    case "Reports":
                        newToolStripMenuItem1.Visible = true;
                        reportToolStripMenuItem.Visible = true;
                        folderToolStripMenuItem.Visible = true;

                        break;

                    case "Dashboards":
                        newToolStripMenuItem1.Visible = true;
                        dashboardToolStripMenuItem.Visible = true;
                        folderToolStripMenuItem.Visible = true;

                        break;

                    case "Charts":
                        newToolStripMenuItem1.Visible = true;
                        chartToolStripMenuItem.Visible = true;
                        folderToolStripMenuItem.Visible = true;

                        break;

                    case "Control Charts":
                        newToolStripMenuItem1.Visible = true;
                        controlChartToolStripMenuItem.Visible = true;
                        folderToolStripMenuItem.Visible = true;

                        break;


                    case "Roles":
                        newToolStripMenuItem1.Visible = true;
                        roleToolStripMenuItem.Visible = true;
                        folderToolStripMenuItem.Visible = true;

                        break;

                    case "Users":
                        newToolStripMenuItem1.Visible = true;
                        userToolStripMenuItem.Visible = true;
                        folderToolStripMenuItem.Visible = true;
                                              
                        break;

                    case "External Connections":
                        newToolStripMenuItem1.Visible = true;
                        externalConnectionToolStripMenuItem.Visible = true;
                        folderToolStripMenuItem.Visible = true;

                        break;


                    case "Products":
                        newToolStripMenuItem1.Visible = true;
                        productToolStripMenuItem.Visible = true;
                        folderToolStripMenuItem.Visible = true;

                        break;

                }
            }
        
            if (listView1.SelectedItems.Count > 0)
                if ((listView1.SelectedItems[0].Tag != null && contextMenuStrip1.SourceControl == listView1)) {
                    if (bag.Context.Service.TestObjectPermission(bag.Module.Guid, PermissionType.Delete)) {
                        deleteToolStripMenuItem.Visible = true;
                    }
                    if (bag.Context.Service.TestObjectPermission(bag.Module.Guid, PermissionType.Modify) ||
                        bag.Context.Service.TestObjectPermission(bag.Module.Guid, PermissionType.View)) {
                        propertiesToolStripMenuItem1.Visible = true;
                    }
                }
        }

        private void folderToolStripMenuItem_Click(object sender, EventArgs e) {
            TreeNode node = treeView1.SelectedNode;
            ConnectionContextBag bag = node.Tag as ConnectionContextBag;

            TreeNode newNode = new TreeNode("", TreeViewIconIndexes.FoldersClosed, TreeViewIconIndexes.FoldersOpened);

            Folder folder = Folder.CreateFolder(Guid.NewGuid());



            ConnectionContextBag newBag = new ConnectionContextBag();
            newBag.Context = bag.Context;
            newBag.Folder = folder;
            newBag.Module = bag.Module;
            newBag.ParentGuid = (bag.Folder == null) ? bag.Module.Guid : bag.Folder.Guid;
            folder.Parent = newBag.ParentGuid;
            folder.Module = bag.Module.Guid;
            bag.Context.Service.AddFolder(folder);
            bag.Context.Service.SaveChanges();
            newNode.Tag = newBag;

            node.Nodes.Add(newNode);


            treeView1.SelectedNode = newNode;

            newNode.BeginEdit();

        }

        private void treeView1_AfterLabelEdit(object sender, NodeLabelEditEventArgs e) {
            ConnectionContextBag bag = (ConnectionContextBag)e.Node.Tag;
            
            if (bag.Folder != null) {
                string oldName = bag.Folder.Name;
                if (e.Label != null && e.Label.Trim() != "") {
                    bag.Folder.Name = e.Label;
                    try {
                        bag.Context.Service.UpdateFolder(bag.Folder);
                        e.Node.Text = e.Label;
                    } catch (ObjectAlreadyCreatedException oace) {
                        MessageBox.Show("There is another folder with the name '" + e.Label + "' in this parent folder", "Attention!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        bag.Folder.Name = oldName;
                        e.CancelEdit = true;
                    }

                } else {
                    e.CancelEdit = true;
                }
            }

        }

        private void treeView1_AfterSelect(object sender, TreeViewEventArgs e) {
            if (e.Node.Tag is ConnectionContextBag) {
                PopulateNode(e.Node);
            } else if (e.Node.Tag is ConnectionContext) {
                ConnectionContext context = e.Node.Tag as ConnectionContext;
                listView1.Items.Clear();
                ListViewItem item;
                if (context.Service.TestObjectPermission(FindModule(modules, "Process Models").Guid, QualityStormCommon.PermissionType.View)) {
                    item = new ListViewItem("Process Models", TreeViewIconIndexes.ProcessModels);
                    listView1.Items.Add(item);
                }

                if (context.Service.TestObjectPermission(FindModule(modules, "Queries").Guid, QualityStormCommon.PermissionType.View)) {
                    item = new ListViewItem("Queries", TreeViewIconIndexes.Queries);
                    listView1.Items.Add(item);
                }

                if (context.Service.TestObjectPermission(FindModule(modules, "Reports").Guid, QualityStormCommon.PermissionType.View)) {
                    item = new ListViewItem("Reports", TreeViewIconIndexes.Reports);
                    listView1.Items.Add(item);
                }

                if (context.Service.TestObjectPermission(FindModule(modules, "Charts").Guid, QualityStormCommon.PermissionType.View)) {
                    item = new ListViewItem("Charts", TreeViewIconIndexes.Charts);
                    listView1.Items.Add(item);
                }

                if (context.Service.TestObjectPermission(FindModule(modules, "Control Charts").Guid, QualityStormCommon.PermissionType.View)) {
                    item = new ListViewItem("Control Charts", TreeViewIconIndexes.ControlCharts);
                    listView1.Items.Add(item);
                }

                if (context.Service.TestObjectPermission(FindModule(modules, "Dashboards").Guid, QualityStormCommon.PermissionType.View)) {
                    item = new ListViewItem("Dashboards", TreeViewIconIndexes.Dashboards);
                    listView1.Items.Add(item);
                }

                if (context.Service.TestObjectPermission(FindModule(modules, "Users").Guid, QualityStormCommon.PermissionType.View) ||
                    context.Service.TestObjectPermission(FindModule(modules, "Roles").Guid, QualityStormCommon.PermissionType.View) ||
                    context.Service.TestObjectPermission(FindModule(modules, "External Connections").Guid, QualityStormCommon.PermissionType.View)) {
                    item = new ListViewItem("Control Panel", TreeViewIconIndexes.ControlPanel);
                    listView1.Items.Add(item);
                }




            }
        }

        private void listView1_DoubleClick(object sender, EventArgs e) {

        }

        private void listView1_MouseDoubleClick(object sender, MouseEventArgs e) {
            ListViewItem item = listView1.GetItemAt(e.X, e.Y);
            if (item != null) {
                if (item.Tag is Role) {
                    FrmRoles frm = new FrmRoles();
                    frm.ContextBag = ((ConnectionContextBag)treeView1.SelectedNode.Tag);
                    frm.ReadOnly = !frm.ContextBag.Context.Service.TestObjectPermission(frm.ContextBag.Module.Guid, PermissionType.Modify);
                    frm.Role = item.Tag as Role;
                    frm.ShowDialog();
                    if (frm.DialogResult == DialogResult.OK) {
                        item.Text = frm.Role.Name;
                    }
                }

                if (item.Tag is User) {
                    FrmUsers frm = new FrmUsers();
                    frm.ContextBag = ((ConnectionContextBag)treeView1.SelectedNode.Tag);
                    frm.User = item.Tag as User;
                    frm.ReadOnly = !frm.ContextBag.Context.Service.TestObjectPermission(frm.ContextBag.Module.Guid, PermissionType.Modify);
                    frm.ShowDialog();
                    if (frm.DialogResult == DialogResult.OK) {
                        if (frm.User.LastName != "") {
                            item.Text = frm.User.LastName + ", " + frm.User.FirstName;
                        } else {
                            item.Text = frm.User.FirstName;
                        }
                    }
                }

                if (item.Tag is Product) {
                    FrmProducts frm = new FrmProducts();
                    frm.ContextBag = ((ConnectionContextBag)treeView1.SelectedNode.Tag);
                    frm.Product = item.Tag as Product;
                    frm.ReadOnly = !frm.ContextBag.Context.Service.TestObjectPermission(frm.ContextBag.Module.Guid, PermissionType.Modify);
                    frm.ShowDialog();
                    if (frm.DialogResult == DialogResult.OK) {
                    
                            item.Text = frm.Product.Name;
                        
                    }
                }

            }
        }

        private void roleToolStripMenuItem_Click(object sender, EventArgs e) {
            ConnectionContextBag context = ((ConnectionContextBag)treeView1.SelectedNode.Tag);
            FrmRoles frm = new FrmRoles();
            frm.ContextBag = context;
            frm.Role = null;

            frm.ShowDialog();
            if (frm.Role != null) {
                Role role = frm.Role;
                ListViewItem item = new ListViewItem();
                item.Text = role.Name;
                item.ImageIndex = TreeViewIconIndexes.Roles;
                item.Tag = role;
                if (char.IsLetter(item.Text[0])) {
                    string letter = item.Text[0].ToString().ToUpper();
                    item.Group = listView1.Groups[letter];
                } else if (char.IsNumber(item.Text[0])) {
                    item.Group = listView1.Groups["0 - 9"];
                } else {
                    item.Group = listView1.Groups["Symbols"];
                }
                listView1.Items.Add(item);
            }
        }

        private void deleteToolStripMenuItem_Click(object sender, EventArgs e) {
            if (MessageBox.Show("Do you really want to delete these items?", "Attention!", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question) == DialogResult.Yes) {
                ConnectionContext context = (treeView1.SelectedNode.Tag as ConnectionContextBag).Context;
                if (contextMenuStrip1.SourceControl == listView1) {
                    foreach (ListViewItem item in listView1.SelectedItems) {
                        if (item.Tag is Role) {
                            context.Service.DeleteRole(item.Tag as Role);
                        }
                        if (item.Tag is User) {
                            if (context.Login == ((User)item.Tag).Login) {
                                MessageBox.Show("A User can't delete itself. Login with a different account and try it again.", "Attention!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            } else {
                                context.Service.DeleteUser(item.Tag as User);
                                return;
                            }
                        }

                        if (item.Tag is Product) {
                            context.Service.DeleteProduct(item.Tag as Product);
                        }

                        listView1.Items.Remove(item);
                    }
                }

            }
        }

        private void propertiesToolStripMenuItem1_Click(object sender, EventArgs e) {
            ConnectionContextBag bag = (treeView1.SelectedNode.Tag as ConnectionContextBag);
            if (contextMenuStrip1.SourceControl == listView1) {
                foreach (ListViewItem item in listView1.SelectedItems) {
                    if (item.Tag is Role) {
                        FrmRoles frm = new FrmRoles(treeView1.SelectedNode.Tag as ConnectionContextBag);
                        frm.ReadOnly = !bag.Context.Service.TestObjectPermission(bag.Module.Guid, PermissionType.Modify);
                        frm.Role = item.Tag as Role;
                        frm.ShowDialog();
                        if (frm.DialogResult == DialogResult.OK) {
                            item.Text = frm.Role.Name;
                        }
                    }

                    if (item.Tag is User) {
                        FrmUsers frm = new FrmUsers(treeView1.SelectedNode.Tag as ConnectionContextBag);
                        frm.User = item.Tag as User;
                        frm.ReadOnly = ! bag.Context.Service.TestObjectPermission(bag.Module.Guid, PermissionType.Modify);
                        frm.ShowDialog();
                        if (frm.DialogResult == DialogResult.OK) {
                            if (frm.User.LastName == "") {
                                item.Text = frm.User.FirstName;
                            } else {
                                item.Text = frm.User.LastName + ", " + frm.User.FirstName;
                            }
                        }
                    }

                    if (item.Tag is ExternalConnection) {
                        FrmExternalConnections frm = new FrmExternalConnections(treeView1.SelectedNode.Tag as ConnectionContextBag);
                        frm.ExternalConnection = item.Tag as ExternalConnection;
                        frm.ReadOnly = !bag.Context.Service.TestObjectPermission(bag.Module.Guid, PermissionType.Modify);
                        frm.ShowDialog();
                        if (frm.DialogResult == DialogResult.OK) {

                            item.Text = frm.ExternalConnection.Name;

                        }
                    }

                    if (item.Tag is Product) {
                        FrmProducts frm = new FrmProducts(treeView1.SelectedNode.Tag as ConnectionContextBag);
                        frm.Product = item.Tag as Product;
                        frm.ReadOnly = !bag.Context.Service.TestObjectPermission(bag.Module.Guid, PermissionType.Modify);
                        frm.ShowDialog();
                        if (frm.DialogResult == DialogResult.OK) {

                            item.Text = frm.Product.Name;
                            
                        }
                    }

                    if (item.Tag is ProcessModel) {
                        FrmProcessModels frm = new FrmProcessModels(treeView1.SelectedNode.Tag as ConnectionContextBag);
                        frm.ProcessModel = item.Tag as ProcessModel;
                        frm.ReadOnly = !bag.Context.Service.TestObjectPermission(bag.Module.Guid, PermissionType.Modify);
                        frm.ShowDialog();
                        if (frm.DialogResult == DialogResult.OK) {

                            item.Text = frm.ProcessModel.Name;

                        }
                    }

                }
            }

        }

        private void userToolStripMenuItem_Click(object sender, EventArgs e) {
            ConnectionContextBag context = ((ConnectionContextBag)treeView1.SelectedNode.Tag);
            FrmUsers frm = new FrmUsers();
            frm.ContextBag = context;
            frm.User = null;

            frm.ShowDialog();
            if (frm.User != null) {
                User user = frm.User;
                ListViewItem item = new ListViewItem();
                if (user.LastName == "") {
                    item.Text = user.FirstName;
                } else {
                    item.Text = user.LastName + ", " + user.FirstName;
                }

                item.ImageIndex = TreeViewIconIndexes.Users;
                item.Tag = user;
                if (char.IsLetter(item.Text[0])) {
                    string letter = item.Text[0].ToString().ToUpper();
                    item.Group = listView1.Groups[letter];
                } else if (char.IsNumber(item.Text[0])) {
                    item.Group = listView1.Groups["0 - 9"];
                } else {
                    item.Group = listView1.Groups["Symbols"];
                }
                listView1.Items.Add(item);
            }

        }

        private void productsToolStripMenuItem_Click(object sender, EventArgs e) {
            ConnectionContextBag context = ((ConnectionContextBag)treeView1.SelectedNode.Tag);
            FrmProducts frm = new FrmProducts();
            frm.ContextBag = context;
            frm.Product = null;

            frm.ShowDialog();
            if (frm.Product != null) {
                Product product = frm.Product;
                ListViewItem item = new ListViewItem();
                item.Text = product.Name;
                item.ImageIndex = TreeViewIconIndexes.Products;
                item.Tag = product;
                if (char.IsLetter(item.Text[0])) {
                    string letter = item.Text[0].ToString().ToUpper();
                    item.Group = listView1.Groups[letter];
                } else if (char.IsNumber(item.Text[0])) {
                    item.Group = listView1.Groups["0 - 9"];
                } else {
                    item.Group = listView1.Groups["Symbols"];
                }
                listView1.Items.Add(item);
            }

        }

        private void externalConnectionToolStripMenuItem_Click(object sender, EventArgs e) {
            ConnectionContextBag context = ((ConnectionContextBag)treeView1.SelectedNode.Tag);
            FrmExternalConnections frm = new FrmExternalConnections();
            frm.ContextBag = context;
            frm.ExternalConnection = null;

            frm.ShowDialog();
            if (frm.ExternalConnection != null) {
                ExternalConnection externalConnection = frm.ExternalConnection;
                ListViewItem item = new ListViewItem();
                item.Text = externalConnection.Name;
                item.ImageIndex = TreeViewIconIndexes.ExternalConnections;
                item.Tag = externalConnection;
                if (char.IsLetter(item.Text[0])) {
                    string letter = item.Text[0].ToString().ToUpper();
                    item.Group = listView1.Groups[letter];
                } else if (char.IsNumber(item.Text[0])) {
                    item.Group = listView1.Groups["0 - 9"];
                } else {
                    item.Group = listView1.Groups["Symbols"];
                }
                listView1.Items.Add(item);
            }


        }

        private void processModelToolStripMenuItem_Click(object sender, EventArgs e) {
            ConnectionContextBag context = ((ConnectionContextBag)treeView1.SelectedNode.Tag);
            FrmProcessModels frm = new FrmProcessModels();
            frm.ContextBag = context;
            frm.ProcessModel = null;

            frm.ShowDialog();
            if (frm.ProcessModel != null) {
                ProcessModel processModel = frm.ProcessModel;
                ListViewItem item = new ListViewItem();
                item.Text = processModel.Name;
                item.ImageIndex = TreeViewIconIndexes.ProcessModels;
                item.Tag = processModel;
                if (char.IsLetter(item.Text[0])) {
                    string letter = item.Text[0].ToString().ToUpper();
                    item.Group = listView1.Groups[letter];
                } else if (char.IsNumber(item.Text[0])) {
                    item.Group = listView1.Groups["0 - 9"];
                } else {
                    item.Group = listView1.Groups["Symbols"];
                }
                listView1.Items.Add(item);
            }

        }
    }

    public class ConnectionContextBag {

        private ConnectionContext m_Context;
        private Module m_Module;
        private Guid m_ParentGuid;
        private Folder m_Folder;

        public ConnectionContext Context {
            get {
                return m_Context;
            }
            set {
                m_Context = value;
            }
        }

        public Module Module {
            get {
                return m_Module;
            }
            set {
                m_Module = value;
            }
        }


        public Guid ParentGuid {
            get {
                return m_ParentGuid;
            }
            set {
                m_ParentGuid = value;
            }

        }

        public Folder Folder {
            get {
                return m_Folder;
            }
            set {
                m_Folder = value;
            }
        }

    }
}
